<?php

/* this is the dbAccess toolkit
*/
	include_once("DB.php");

	define("E_OK","0");
	define("E_DB_CONNECT_FAIL","-10");
	define("E_DB_SELECT_FAIL","-11");
	define("E_DB_QUERY_FAIL","-12");
	define("E_DB_ROWOP_FAIL","-13");
	define("E_DB_EMPTY_SET","-14");
	define("E_DB_COMMIT_FAIL","-15");
	define("E_DB_ROLLBACK_FAIL","-16");
	define("E_DB_AUTOCOMMIT_SET_FAIL","-17");
	define("E_SEQ_ERROR","-18");


	/**
		dbConnection object.
	*/
	class CmsDatabaseConnection {

		/**
			connection details
		*/

		var $dsn;		// the database dsn
		var $db;		// the pear db object ..
		var $connected;	// are we connected?
		var $link; 		// the database link.. not really needed
		var $dbResultSet;	// the working result set
		var $lastError;		// the last encountered error
		var $autoCommitMode;// are we in autocommit or not13

		/**
			dbConnection constructor;

			connects to the specified server and selects the specified database using the given user info.
		*/
		function CmsDatabaseConnection($dsn){
			$this->dsn = $dsn;
			$this->connect();
		}

		function connect(){
			$result = $this->db = DB::connect($this->dsn, true);
			
			if (DB::isError($result)){
				$this->connected = FALSE;
				$this->lastError = $result;
				return FALSE;
			} else {
				$this->connected = TRUE;
				$this->lastError = E_OK;
				return TRUE;
			}
			
		}

		/**
			checks to see if we can execute queries with this connection
		*/
		function canExecuteQueries(){
			return $this->isConnected();
		}

		/**
			checks to see if we are connected
		*/
		function isConnected(){
			return $this->connected;
		}

		/**
			executes a query on the database and assigns the result set to the internal result pointer
		*/
		function executeQuery($queryString){

			if (CMS_QUERY_DEBUG)
				echo "query: " . $queryString;

			$this->dbResultSet = &$this->db->query($queryString);

			if (CMS_QUERY_DEBUG)
				myPrintR( $this->dbResultSet ,"result set: executeQuery");
				
			if (DB::isError($this->dbResultSet)) {
    				$this->lastError = $this->dbResultSet;
    				return FALSE;
			} else {
				$this->lastError = E_OK;
				return TRUE;
			}
		}

		
		function prepareAndExecuteQuery($query, $fields){
		
			if (CMS_QUERY_DEBUG)
				echo $query;	
				
			$stmt = $this->db->prepare($query);
			
			$this->dbResultSet = &$this->db->execute($stmt, $fields);
			
			if (DB::isError($this->dbResultSet)) {
    				$this->lastError = $this->dbResultSet;
    				return false;
			} else {
				$this->lastError = E_OK;
				return true;
			}			
		}
		
		function &fetch($fetchType){
			
			if ($this->lastError != E_OK) {
				$f = (false);
				return $f;
			}
			
			if ( CMS_QUERY_DEBUG && !is_object($this->dbResultSet)) {
				myPrintR($this->dbResultSet,"result set: fetch");
				myPrintR( debug_backtrace(), "trace: fetch");
			}
			
			$res = &$this->dbResultSet->fetchRow($fetchType);
			if (DB::isError($res)){
				$this->lastError = $res;
				$f = false;
				return $f;
			} else {
				$this->lastError = E_OK;
				return $res;
			}
		}

		function nextRow(){
			return $this->fetch(DB_FETCHMODE_ORDERED);
		}

		function nextAssoc(){
			return $this->fetch(DB_FETCHMODE_ASSOC);
		}

		function nextObject(){
			return $this->fetch(DB_FETCHMODE_OBJECT);
		}

		function numRows(){
			
			if ($this->lastError != E_OK) {
				return FALSE;
			}
			
			if ( CMS_QUERY_DEBUG && !is_object($this->dbResultSet)) {
				myPrintR($this->dbResultSet,"result set: numRows");
				myPrintR( debug_backtrace(), "trace: numRows");
			}
						
			$res = is_object($this->dbResultSet) ? $this->dbResultSet->numRows() : NULL;
			
			if (DB::isError($res)){
				$this->lastError = $res;
				return FALSE;
			} else {
				return $res;
			}
			
		}

		function numFields(){
		
			if ($this->lastError != E_OK) {
				return FALSE;
			}

			if ( CMS_QUERY_DEBUG && !is_object($this->dbResultSet)) {
				myPrintR($this->dbResultSet,"result set: numFields");
				myPrintR( debug_backtrace(),"trace" );
			}
			
			$res = $this->dbResultSet->numRows();
			
			if (DB::isError($res)){
				$this->lastError = $res;
				return FALSE;
			} else {
				return $res;
			}
			
		}

		function commit(){
		
			$res = $this->db->commit();
			
			if (DB::isError($res)){
				$this->lastError = $res;
				return FALSE;
			} else {
				return TRUE;
			}
			
		}

		function rollback(){
		
			$res = $this->db->rollback();
			
			if (DB::isError($res)){
				$this->lastError = $res;
				return FALSE;
			} else {
				return TRUE;
			}
			
		}

		function autoCommit($autoCommitMode){
		
			$res = $this->db->autoCommit($autoCommitMode);
			
			if (DB::isError($res)){
				$this->lastError = $res;
				return FALSE;
			} else {
				$this->autoCommitMode = $autoCommitMode;
				return TRUE;
			}
		}

		function getAutoCommitMode(){
			return $this->autoCommitMode;
		}


		function setResultSet(&$dbResultSet){
			$this->dbResultSet = $dbResultSet;
		}

		function &getResultSet(){
			return $this->dbResultSet;
		}
		

// THIS HAS BEEN DEPRECATED.. IT IS EVIl
//		function quoteString($string){
//			die("dbConnection quote string considered evil");
//		}

		function getId($sequenceName) {
			
			$id = $this->db->nextId($sequenceName);
			
			if (DB::isError( $id )) {
				$this->lastError = $id;
				return false;
			} else {
				$this->lastError = E_OK;
				return $id;
			}

		}

		//add a static cache here for the table info...
		function getTableInfo($table) {
			static $tableInfoCache =null;
			if ( is_null($tableInfoCache)) {
				$tableInfoCache = array();
			}

			if ( key_exists($table, $tableInfoCache))
				return $tableInfoCache[ $table ];
				
			
			$res = $this->db->tableInfo($table);
			
			if (DB::isError( $res )) {
				$this->lastError = $res;
				return false;
			} else {
				$this->lastError = E_OK;
				$tableInfoCache[ $table ] = $res;
				return $res;
			}
		}
		
		/** no db agnostic version of this */
		function getAffectedRows(){
			return mysql_affected_rows();
		}
		
		function &getAll($query, &$values, $fetchType) {

			if (is_null($values))
				$values = array();
				
			$res =& $this->db->getAll($query, $values, $fetchType);

//			$res = $this->db->getAll($query, $values, $fetchType);
			if (DB::isError( $res )) {
				$this->lastError = $res;
				$f = (false);
				return $f;
			} else {
				$this->lastError = E_OK;
				return $res;
			}
			return $res;
		}
		
				
		function getAllAsArray($query, &$values){
			return $this->getAll( $query, $values, DB_FETCHMODE_ORDERED);						
		}
		
		function getAllAsObjects($query, &$values){
			return $this->getAll( $query, $values, DB_FETCHMODE_OBJECT);			
		}
		
		function getAllAsAssociativeArray($query, &$values){
			return $this->getAll( $query, $values, DB_FETCHMODE_ASSOC);
		}
		
		
		
	}